package com.quanshi.shopping_user_service.util;

import lombok.SneakyThrows;
import org.jose4j.json.JsonUtil;
import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

public class JwtUtils {
    // 私钥
    public final static String PRIVATE_JSON = "{\"kty\":\"RSA\",\"n\":\"2XV57wcwOzoW9dM9UE0MUTKO6odgGy7J2eAj7rdBFkMxZv000FxEZFs5CYtmpmftAoZrxywmPX0lPqKLBtTx2xXoDXwCQSfsxSdPCINoD4OYpFyP0_KTBi4EHtZe5Ueg_ZIdKNMr6033MNisjXHXYtpfvgXRA2ysnF0sU5OXgCH2IVF-da_o8GBpVndRsJ0pBMar-X1-nnz63yqMW2ntuk8naKakdR8iEJOct90R_NDaaY8Dhn7r_09KEeQpJ48ytjoa99QGCAsC2c0Xv0C9lSSgGuBTgbSL5UeI4335_S6qG6t5Wq52f-RVYTkbPelWRfJ9IQzUaevUDwa875Cbfw\",\"e\":\"AQAB\",\"d\":\"EjmGvRIgqC4Po42PG25BpIJ0uNIcq1qJ_zEKQeTo1wlNmCCLbxT0hGaiypp8wWB_XBFQ8hHQqKGW3_92YF2zYVWeK5cjhztl3AYV2RROQdKZFdlOEojHaqKrpLv5mwScSPQYboX4LdHMcDMQjxAl6Xp8wKuzHzLZ6obigqShc1L9re6bhzoQ12Nqc9nBHnlapbSB07rPqNdnvxPf144y1i1eAU4TXc-Uyfg9A8-i-B4Si29ctEeueFkNo0AO-r1sxJZ2EX4yEeLjbq0tSjOcyXGLP0GW1rJhd0SBsEDKGjdmxOP_cWuPj3uwzfV4R5w8UmqUVhJ4EEywCp6E-t6q6Q\",\"p\":\"_LwHqeAlzWlHprKJkYYngwrCmmmlIYUJlYY-V8v3LsHSLDdr-RjwQPx8JThscnz9Mc0JsblT5_T2zVmYp6UYWBVcfDiXHB5GsXr1toivztwE2lyyBzyotiJtYO_5u0LYVwThQBOpOe-vE6KrR-2iR7RvvbV6I9EbwbKbUzIQ5Hk\",\"q\":\"3ETD5rkHIg4cbTGQWPx1LTW89w26y6Al1ZsgCczCr3qcbw3lUf4a8v9NgrpwnCep9ZX5_6tzpO7wPy6OYQ5Lt430f3OCYavTT6SWLOB73aNphbYgB_lju2WWvPiw8yat_y3fTHvx3xY-bOW3UdR7um6a7RERQBH8CAvOc9wLUbc\",\"dp\":\"tpVYq_8FEFrIqsM842cZ0G_LmyZLZ-XmwKEVFPSDhMH9hngbhv_fQfOl9HXI0wU9HedU45JR7bdpPX1G7YY2ChyUjiGL-YJd7AY60T36VOValC53ZwcJk1tXzbpQnlpyVJtv54zMqtBfmT3ho7sni8ntGA6tSIbfGJZh5D69OXE\",\"dq\":\"LQbtmPuX5rFFxFiObnJlLbG_iC1JUxjQwyKr4PT3k1GYKueHSkSMk8H2wVOFc5Z0GtzmtwoAYOXrPK8yscpvVf1xzp_5Nige0TgO7uuQxpUCHDBHyfmEFqnEr6qS2ZG9nd1tuT_ZCMaOSkqHN_YcuNalWvLTOOq0P5zSPkLsGW8\",\"qi\":\"haFnyWXv-k7nHrf65hnG29nLY6E0zt-9iJnX7yc0XJqpUtJ6PD-PoFkCnutVl8jKPCSbewfaQ0YsHNV8iibxVDxJ_894Bt-25VsNS11blW22aJ_MwkeNDWftCG75Ip-EkODgFBjw9WYWO6fQI6MVA6GO6QkcfKs4ZrSceP-9RK8\"}";
    // 公钥
    public final static String PUBLIC_JSON = "{\"kty\":\"RSA\",\"n\":\"2XV57wcwOzoW9dM9UE0MUTKO6odgGy7J2eAj7rdBFkMxZv000FxEZFs5CYtmpmftAoZrxywmPX0lPqKLBtTx2xXoDXwCQSfsxSdPCINoD4OYpFyP0_KTBi4EHtZe5Ueg_ZIdKNMr6033MNisjXHXYtpfvgXRA2ysnF0sU5OXgCH2IVF-da_o8GBpVndRsJ0pBMar-X1-nnz63yqMW2ntuk8naKakdR8iEJOct90R_NDaaY8Dhn7r_09KEeQpJ48ytjoa99QGCAsC2c0Xv0C9lSSgGuBTgbSL5UeI4335_S6qG6t5Wq52f-RVYTkbPelWRfJ9IQzUaevUDwa875Cbfw\",\"e\":\"AQAB\"}";


    /**
     * 生成token
     *
     * @param userId    用户id
     * @param username 用户名字
     * @return
     */
    @SneakyThrows
    public static String sign(Long userId, String username) {
        // 1、 创建jwtclaims  jwt内容载荷部分
        JwtClaims claims = new JwtClaims();
        // 是谁创建了令牌并且签署了它
        claims.setIssuer("quanshi");
        // 令牌将被发送给谁
        claims.setAudience("audience");
        // 失效时间长 （分钟）
        claims.setExpirationTimeMinutesInTheFuture(60 * 24);
        // 令牌唯一标识符
        claims.setGeneratedJwtId();
        // 当令牌被发布或者创建现在
        claims.setIssuedAtToNow();
        // 再次之前令牌无效
        claims.setNotBeforeMinutesInThePast(2);
        // 主题
        claims.setSubject("shopping");
        // 可以添加关于这个主题得声明属性
        claims.setClaim("userId", userId);
        claims.setClaim("username", username);


        // 2、签名
        JsonWebSignature jws = new JsonWebSignature();
        //赋值载荷
        jws.setPayload(claims.toJson());


        // 3、jwt使用私钥签署
        PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(PRIVATE_JSON)).getPrivateKey();
        jws.setKey(privateKey);


        // 4、设置关键 kid
        jws.setKeyIdHeaderValue("keyId");


        // 5、设置签名算法
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
        // 6、生成jwt
        String jwt = jws.getCompactSerialization();
        return jwt;
    }




    /**
     * 解密token，获取token中的信息
     *
     * @param token
     */
    @SneakyThrows
    public static Map<String, Object> verify(String token){
        // 1、引入公钥
        PublicKey publicKey = new RsaJsonWebKey(JsonUtil.parseJson(PUBLIC_JSON)).getPublicKey();
        // 2、使用jwtcoonsumer  验证和处理jwt
        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                .setRequireExpirationTime() //过期时间
                .setAllowedClockSkewInSeconds(30) //允许在验证得时候留有一些余地 计算时钟偏差  秒
                .setRequireSubject() // 主题生命
                .setExpectedIssuer("quanshi") // jwt需要知道谁发布得 用来验证发布人
                .setExpectedAudience("audience") //jwt目的是谁 用来验证观众
                .setVerificationKey(publicKey) // 用公钥验证签名  验证密钥
                .setJwsAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, AlgorithmIdentifiers.RSA_USING_SHA256))
                .build();
        // 3、验证jwt 并将其处理为 claims
        try {
            JwtClaims jwtClaims = jwtConsumer.processToClaims(token);
            return jwtClaims.getClaimsMap();
        }catch (Exception e){
            return new HashMap();
        }
    }

    public static void main(String[] args) throws JoseException {

        //发放令牌
        String token = JwtUtils.sign(30L, "xiaoming");
        System.out.println("token = " + token);
        //校验令牌
        Map<String, Object> map = JwtUtils.verify(token);
        System.out.println("map = " + map);

//        RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
//        final String publicKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
//        final String privateKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
//        System.out.println(publicKeyString);
//        //{"kty":"RSA","n":"2XV57wcwOzoW9dM9UE0MUTKO6odgGy7J2eAj7rdBFkMxZv000FxEZFs5CYtmpmftAoZrxywmPX0lPqKLBtTx2xXoDXwCQSfsxSdPCINoD4OYpFyP0_KTBi4EHtZe5Ueg_ZIdKNMr6033MNisjXHXYtpfvgXRA2ysnF0sU5OXgCH2IVF-da_o8GBpVndRsJ0pBMar-X1-nnz63yqMW2ntuk8naKakdR8iEJOct90R_NDaaY8Dhn7r_09KEeQpJ48ytjoa99QGCAsC2c0Xv0C9lSSgGuBTgbSL5UeI4335_S6qG6t5Wq52f-RVYTkbPelWRfJ9IQzUaevUDwa875Cbfw","e":"AQAB"}
//        System.out.println(privateKeyString);
//        //{"kty":"RSA","n":"2XV57wcwOzoW9dM9UE0MUTKO6odgGy7J2eAj7rdBFkMxZv000FxEZFs5CYtmpmftAoZrxywmPX0lPqKLBtTx2xXoDXwCQSfsxSdPCINoD4OYpFyP0_KTBi4EHtZe5Ueg_ZIdKNMr6033MNisjXHXYtpfvgXRA2ysnF0sU5OXgCH2IVF-da_o8GBpVndRsJ0pBMar-X1-nnz63yqMW2ntuk8naKakdR8iEJOct90R_NDaaY8Dhn7r_09KEeQpJ48ytjoa99QGCAsC2c0Xv0C9lSSgGuBTgbSL5UeI4335_S6qG6t5Wq52f-RVYTkbPelWRfJ9IQzUaevUDwa875Cbfw","e":"AQAB","d":"EjmGvRIgqC4Po42PG25BpIJ0uNIcq1qJ_zEKQeTo1wlNmCCLbxT0hGaiypp8wWB_XBFQ8hHQqKGW3_92YF2zYVWeK5cjhztl3AYV2RROQdKZFdlOEojHaqKrpLv5mwScSPQYboX4LdHMcDMQjxAl6Xp8wKuzHzLZ6obigqShc1L9re6bhzoQ12Nqc9nBHnlapbSB07rPqNdnvxPf144y1i1eAU4TXc-Uyfg9A8-i-B4Si29ctEeueFkNo0AO-r1sxJZ2EX4yEeLjbq0tSjOcyXGLP0GW1rJhd0SBsEDKGjdmxOP_cWuPj3uwzfV4R5w8UmqUVhJ4EEywCp6E-t6q6Q","p":"_LwHqeAlzWlHprKJkYYngwrCmmmlIYUJlYY-V8v3LsHSLDdr-RjwQPx8JThscnz9Mc0JsblT5_T2zVmYp6UYWBVcfDiXHB5GsXr1toivztwE2lyyBzyotiJtYO_5u0LYVwThQBOpOe-vE6KrR-2iR7RvvbV6I9EbwbKbUzIQ5Hk","q":"3ETD5rkHIg4cbTGQWPx1LTW89w26y6Al1ZsgCczCr3qcbw3lUf4a8v9NgrpwnCep9ZX5_6tzpO7wPy6OYQ5Lt430f3OCYavTT6SWLOB73aNphbYgB_lju2WWvPiw8yat_y3fTHvx3xY-bOW3UdR7um6a7RERQBH8CAvOc9wLUbc","dp":"tpVYq_8FEFrIqsM842cZ0G_LmyZLZ-XmwKEVFPSDhMH9hngbhv_fQfOl9HXI0wU9HedU45JR7bdpPX1G7YY2ChyUjiGL-YJd7AY60T36VOValC53ZwcJk1tXzbpQnlpyVJtv54zMqtBfmT3ho7sni8ntGA6tSIbfGJZh5D69OXE","dq":"LQbtmPuX5rFFxFiObnJlLbG_iC1JUxjQwyKr4PT3k1GYKueHSkSMk8H2wVOFc5Z0GtzmtwoAYOXrPK8yscpvVf1xzp_5Nige0TgO7uuQxpUCHDBHyfmEFqnEr6qS2ZG9nd1tuT_ZCMaOSkqHN_YcuNalWvLTOOq0P5zSPkLsGW8","qi":"haFnyWXv-k7nHrf65hnG29nLY6E0zt-9iJnX7yc0XJqpUtJ6PD-PoFkCnutVl8jKPCSbewfaQ0YsHNV8iibxVDxJ_894Bt-25VsNS11blW22aJ_MwkeNDWftCG75Ip-EkODgFBjw9WYWO6fQI6MVA6GO6QkcfKs4ZrSceP-9RK8"}
    }
}
